package com.sbtr.business.trainingserver.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sbtr.business.project.service.impl.ProjectServiceImpl;
import com.sbtr.business.trainingserver.service.ITrainingServerHttpApi;
import com.sbtr.open.project.dto.ProjectDto;
import com.sbtr.open.trainingserver.dto.TrainingServerDto;
import com.sbtr.open.trainingtask.dto.TrainingInfoDto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//import com.sbtr.business.trainingtask.dto.TrainingTaskDto;
//import com.sbtr.business.trainingtask.dto.TrainingTaskFeatureDto;

@Transactional
@Service
public class TrainingServerHttpApiImpl implements ITrainingServerHttpApi {

	private static final Logger logger = LoggerFactory.getLogger(TrainingServerHttpApiImpl.class);

	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private ProjectServiceImpl projectService;

	/**
	 * 标定文件存放路径
	 */
	@Value("${training-task.txt-base-dir}")
	private String txtBaseDir;

	/**
	 * 模型存放路径
	 */
	@Value("${training-task.model-base-dir}")
	private String modelBaseDir;

	@Override
	public long getWaitTime(TrainingServerDto serverDto) {

		String url = "http://" + serverDto.getIp() + "/getWaitTime";
		HttpHeaders headers = this.initRestTemplateHeader();
		// 请求体
		Map<String, Object> postParameters = new HashMap<>();
		String jsonBody = JSON.toJSONString(postParameters);
		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);

		// 返回结果
		String body = postForEntity.getBody();
		JSONObject jsObj = JSONObject.parseObject(body);
		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
			return jsObj.getLong("waittime");
		} else {
			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
			logger.error("状态码: " + ret + ", msg: " + msg);
		}
		return Long.MAX_VALUE;
	}

//	@Override
//	public boolean addTask(TrainingServerDto serverDto, TrainingTaskDto taskDto) {
//		String url = "http://" + serverDto.getIp() + "/addTask";
//		logger.info("启动训练任务请求地址:{} ",url);
//		HttpHeaders headers = this.initRestTemplateHeader();
//		// 请求体
//		Map<String, Object> postParameters = new HashMap<>();
//		postParameters.put("taskid", taskDto.getId().toString());
//		postParameters.put("tasktype", taskDto.getType().equals("9") ? 0L : Long.parseLong(taskDto.getType()));
//		postParameters.put("classnum", Long.parseLong(taskDto.getClassNum()));
//		String datalabel = txtBaseDir + File.separator + taskDto.getId() + ".txt";
//		postParameters.put("datalabel", datalabel);
//		postParameters.put("savepath", modelBaseDir + File.separator);
//		if (taskDto.getMaxepochs() != null) {
//			postParameters.put("maxepochs", taskDto.getMaxepochs());
//		}
//		if (taskDto.getBatchsize() != null) {
//			postParameters.put("batchsize", taskDto.getBatchsize());
//		}
//		// 声音检测要带上的参数
//		if ("3".equals(taskDto.getType())) {
//			postParameters.put("cuttime", taskDto.getCuttime());
//		}
//
//		// 额外参数
//		String extraParam = taskDto.getExtraParam();
//		if (StringUtils.isNotBlank(extraParam)) {
//			JSONObject extraJson = JSONObject.parseObject(extraParam);
//			for (Entry<String, Object> entry : extraJson.entrySet()) {
//				if (entry.getValue() != null) {
//					postParameters.put(entry.getKey(), entry.getValue());
//				}
//			}
//		}
//
//		String jsonBody = JSON.toJSONString(postParameters);
//		logger.info("启动训练任务参数: {}",jsonBody);
//		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
//		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);
//
//		// 返回结果
//		String body = postForEntity.getBody();
//		JSONObject jsObj = JSONObject.parseObject(body);
//		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
//			return true;
//		} else {
//			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
//			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
//			logger.error("状态码: {},msg:{}", ret, msg);
//		}
//		return false;
//	}
//

	@Override
	public boolean addTask(TrainingServerDto serverDto, TrainingInfoDto taskDto) {
		String url = "http://" + serverDto.getIp() + "/addTask";
		logger.info("启动{}训练任务请求地址:{} ",taskDto.getId().toString(),url);
		HttpHeaders headers = this.initRestTemplateHeader();
		// 请求体
		Map<String, Object> postParameters = new HashMap<>();
		postParameters.put("taskid", taskDto.getId().toString());
		postParameters.put("fileid", taskDto.getFileId().toString());
		postParameters.put("projectid", taskDto.getProjectId().toString());
		ProjectDto projectDto = projectService.findById(taskDto.getProjectId());
		postParameters.put("projectType", projectDto.getProjectType());

		String jsonBody = JSON.toJSONString(postParameters);
		logger.info("启动训练任务参数: {}",jsonBody);
		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
//		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);

		AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();

		ListenableFuture<ResponseEntity<String>> forEntity = asyncRestTemplate.postForEntity(url, r, String.class);

		forEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
			@Override
			public void onFailure(Throwable ex) {
				logger.error(String.format("添加训练任务 %s 参数为 %s 请求失败，%s", url, JSON.toJSONString(r), ex.getMessage()));
			}
			@Override
			public void onSuccess(ResponseEntity<String> result) {
				logger.info(String.format("添加训练任务 %s 参数为 %s 请求成功，返回值为 %s", url, JSON.toJSONString(r), JSON.toJSONString(result.getBody())));
			}
		});
		logger.info(taskDto.getId().toString()+"训练任务提前返回");
		return true;

//		// 返回结果
//		String body = postForEntity.getBody();
//		JSONObject jsObj = JSONObject.parseObject(body);
//		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
//			logger.info("添加{}训练任务请求成功",taskDto.getId().toString());
//			return true;
//		} else {
//			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
//			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
//			logger.error("状态码: {},msg:{}", ret, msg);
//		}
//		return false;
	}


//	// 数据类预测接口
//	@Override
//	public boolean addDataTypeTask(TrainingServerDto serverDto,TrainingTaskDataDto taskDto) {
//		String url = "http://" + serverDto.getIp().trim() + "/addTask";
//		logger.info("启动训练任务请求地址:{} ",url);
//		HttpHeaders headers = this.initRestTemplateHeader();
//		// 请求体
//		Map<String, Object> postParameters = new HashMap<>();
//		postParameters.put("taskid", taskDto.getId().toString());
//		postParameters.put("projectid", taskDto.getProjectId());
//		postParameters.put("calibrationsetid", taskDto.getCalibrationSetId());
//
//
//		String jsonBody = JSON.toJSONString(postParameters);
//		logger.info("启动训练任务参数:{} ",jsonBody);
//		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
//		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);
//
//		// 返回结果
//		String body = postForEntity.getBody();
//		JSONObject jsObj = JSONObject.parseObject(body);
//		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
//			return true;
//		} else {
//			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
//			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
//			logger.error("状态码: {},msg:{}", ret, msg);
//		}
//		return false;
//	}
//





	@Override
	public boolean stopTask(TrainingServerDto serverDto, long taskId) {
		String url = "http://" + serverDto.getIp() + "/stopTask";
		HttpHeaders headers = this.initRestTemplateHeader();
		// 请求体
		Map<String, Object> postParameters = new HashMap<>();
		postParameters.put("taskid", taskId + "");
		String jsonBody = JSON.toJSONString(postParameters);
		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);

		// 返回结果
		String body = postForEntity.getBody();
		JSONObject jsObj = JSONObject.parseObject(body);
		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
			return true;
		} else {
			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
			logger.error("状态码: {},msg:{}", ret, msg);
		}
		return false;
	}

	@Override
	public List<TaskInfo> getTaskList(TrainingServerDto serverDto) {
		String url = "http://" + serverDto.getIp() + "/getTaskList";
		HttpHeaders headers = this.initRestTemplateHeader();
		// 请求体
		Map<String, Object> postParameters = new HashMap<>();
		String jsonBody = JSON.toJSONString(postParameters);
		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);
		// 返回结果
		String body = postForEntity.getBody();
		JSONObject jsObj = JSONObject.parseObject(body);
		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
			JSONArray jsonArray = jsObj.getJSONArray("tasklist");
			return jsonArray.toJavaList(TaskInfo.class);
		} else {
			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
			logger.error("状态码: {},msg:{}", ret, msg);
		}
		return Collections.emptyList();
	}

	/**
	 * 初始化请求头 设置请求类型和接收类型
	 * 
	 * @return
	 */
	private HttpHeaders initRestTemplateHeader() {

		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
		headers.setContentType(type);// 请求类型
		headers.add("Access-Control-Allow-Origin", "*");
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());// 接收类型
		return headers;
	}

	@Override
	public boolean serverIsOnline(TrainingServerDto serverDto) {
		try {
			// 能正常调用说明gpu服务器正常
			return this.getTaskList(serverDto) != null;
		} catch (Exception e) {
			logger.error("[" + serverDto.getIp() + "] 服务器不可用", e);
			return false;
		}
	}



	@Override
	public boolean stopDataTypeTask(TrainingServerDto serverDto, long taskId) {
		String url = "http://" + serverDto.getIp() + "/stopTask";
		HttpHeaders headers = this.initRestTemplateHeader();
		// 请求体
		Map<String, Object> postParameters = new HashMap<>();
		postParameters.put("taskid", taskId + "");
		String jsonBody = JSON.toJSONString(postParameters);
		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);

		// 返回结果
		String body = postForEntity.getBody();
		JSONObject jsObj = JSONObject.parseObject(body);
		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
			return true;
		} else {
			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
			logger.error("状态码: {},msg:{}", ret, msg);
		}
		return false;
	}

	@Override
	public String getMachineStatus(TrainingServerDto serverDto) {
		String url = "http://" + serverDto.getIp() + "/getMachineStatus";
		HttpHeaders headers = this.initRestTemplateHeader();
		// 请求体
		Map<String, Object> postParameters = new HashMap<>();
		String jsonBody = JSON.toJSONString(postParameters);
		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);

		// 返回结果
		String body = postForEntity.getBody();
		JSONObject jsObj = JSONObject.parseObject(body);
		if (jsObj.getInteger("ret") != null && 2001 == jsObj.getInteger("ret")) {
			return jsObj.getString("taskNum") + "," + jsObj.getString("percent");
		} else {
			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
			logger.error("状态码: {},msg:{}", ret, msg);
		}
		return "NULL";
	}

//	@Override
//	public boolean addFeatureFileTypeTask(TrainingServerDto serverDto, String fileSize, String fileName,
//			String targetName, String algorithm, String variable, TrainingTaskFeatureDto taskDto) {
//		String url = "http://" + serverDto.getIp().trim() + "/addFETask";
//		logger.info("启动训练任务请求地址: {}", url);
//		HttpHeaders headers = this.initRestTemplateHeader();
//		// 请求体
//		Map<String, Object> postParameters = new HashMap<>();
//		postParameters.put("taskid", taskDto.getId().toString());
//		postParameters.put("projectid", taskDto.getProjectId().toString());
//		postParameters.put("modelType", algorithm);
//		postParameters.put("targetName", targetName);
//		postParameters.put("fileSize", fileSize);
//		postParameters.put("fileName", fileName);
//		postParameters.put("variable", variable);
//
//		String jsonBody = JSON.toJSONString(postParameters);
//		logger.info("启动训练任务参数: {}", jsonBody);
//		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
//		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);
//
//		// 返回结果
//		String body = postForEntity.getBody();
//		JSONObject jsObj = JSONObject.parseObject(body);
//		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
//			return true;
//		} else {
//			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
//			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
//			logger.error("状态码: {},msg:{}", ret, msg);
//		}
//		return false;
//	}

//	@Override
//	public boolean addFeatureTaskByDataBaseType(
//			TrainingServerDto serverDto,
//			String sql,
//			Long connId,
//			String targetName,
//			String tableName,
//			String algorithm,
//			String variable,
//			TrainingTaskFeatureDto taskDto) {
//		String url = "http://" + serverDto.getIp().trim() + "/addFETask";
//		logger.info("启动训练任务请求地址: {}",url);
//		HttpHeaders headers = this.initRestTemplateHeader();
//		// 请求体
//		Map<String, Object> postParameters = new HashMap<>();
//		postParameters.put("taskid", taskDto.getId().toString());
//		postParameters.put("projectid", taskDto.getProjectId().toString());
//		postParameters.put("modelType",algorithm);
//		postParameters.put("targetName", targetName);
//		postParameters.put("tableName", tableName);
//		postParameters.put("sql", sql);
//		postParameters.put("connId", connId.toString());
//		postParameters.put("variable", variable);
//
//		String jsonBody = JSON.toJSONString(postParameters);
//		logger.info("启动训练任务参数: {}",jsonBody);
//		HttpEntity<String> r = new HttpEntity<>(jsonBody, headers);
//		ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, r, String.class);
//
//		// 返回结果
//		String body = postForEntity.getBody();
//		JSONObject jsObj = JSONObject.parseObject(body);
//		if (jsObj.getInteger("ret") != null && 0 == jsObj.getInteger("ret")) {
//			return true;
//		} else {
//			Integer ret = jsObj.getInteger("ret") != null ? jsObj.getInteger("ret") : 0;
//			String msg = StringUtils.isNotBlank(jsObj.getString("msg")) ? jsObj.getString("msg") : "";
//			logger.error("状态码: {},msg:{}", ret, msg);
//		}
//		return false;
//	}
}
